#include "m5311.h"
#include "bsp_usart.h"
#include "bsp_usart2.h"
#include "bsp_adc.h"
#include "delay.h"
#include "malloc.h"
#include "FreeRTOS.h"
#include "task.h"
#include "timer.h"
#include "utils.h"
#include <string.h>
#include <stdarg.h> 	 
#include <stdio.h>	
#include <stdlib.h>

int g_opend_lifetime = 3600;
int g_addobj_objectid_smokesensor = 3300;
int g_observe_msgid;
int g_observe_flag;
int g_observe_objectid_smokesensor = 3300;
int g_observe_instanceid;
int g_observe_resourceid;
int g_discover_msgid_smokesensor = 3300;
int g_discover_objectid;
char *g_discover_valuestring_smokesensor = "\"5700\"";
int g_notify_resourceid_5700_smokesensor = 5700;
char smokesensor_value[100] = {0};
u16 g_hardware_times = 0;
u8 g_m5311_miplnotify_flag = 0;

/* ADC1转换的电压值通过MDA方式传到SRAM */
extern __IO uint16_t ADC_ConvertedValue;

/**************************************************************
函数名称 : m5311_power_init
函数功能 : m5311电源初始化
输入参数 : 无
返回值   : 无
备注	 : 初始化时将PA12置于高电平，
           将M5310的PWRKEY引脚与PA12相连

**************************************************************/
void m5311_power_init(void)
{
	GPIO_InitTypeDef  GPIO_InitStruct;
   
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);/* 使能GPIOC时钟 */
 	
    GPIO_InitStruct.GPIO_Pin    = GPIO_Pin_12;
    GPIO_InitStruct.GPIO_Mode   = GPIO_Mode_Out_PP;     /* 推挽输出 */
    GPIO_InitStruct.GPIO_Speed  = GPIO_Speed_50MHz;
    
    GPIO_Init(GPIOA, &GPIO_InitStruct);
}

/**************************************************************
函数名称 : m5311_power_on
函数功能 : m5311 开机
输入参数 : 无
返回值  	 : 无
备注		 : 无
**************************************************************/
void m5311_power_on(void)
{
    GPIO_WriteBit(GPIOA, GPIO_Pin_12, Bit_SET);
    delay_ms(200);
    GPIO_WriteBit(GPIOA, GPIO_Pin_12, Bit_RESET);
    delay_ms(1000);
    GPIO_WriteBit(GPIOA, GPIO_Pin_12, Bit_SET);
}

/**************************************************************
函数名称 : m5311_hardware_reset
函数功能 : m5311硬件复位
输入参数 : 无
返回值  	 : 无
备注		 : 无
**************************************************************/
void m5311_hardware_reset(void)
{
//	GPIO_ResetBits(GPIOA, GPIO_Pin_5);	/* 拉低RESET引脚开始复位 */
//	delay_ms(1000);		
//	GPIO_SetBits(GPIOA, GPIO_Pin_5);	/* 释放RESET引脚 */
}

/**************************************************************
函数名称 : m5311_at_response
函数功能 : 将收到的AT指令应答数据返回给电脑串口
输入参数 : mode：0,不清零USART2_RX_STA;
			     1,清零USART2_RX_STA;
返回值  	 : 无
备注		 : 无
**************************************************************/
void m5311_at_response(u8 mode)
{
	if(USART2_RX_STA & 0X8000) /* 接收到一次数据了 */
	{ 
		USART2_RX_BUF[USART2_RX_STA&0X7FFF]	= 0;	/* 添加结束符 */
		printf("%s\r\n", USART2_RX_BUF);		/* 发送到串口 */
		if(mode)
		{
			USART2_RX_STA = 0;
		}
	} 
}

/**************************************************************
函数名称 : m5311_clear_recv
函数功能 : 清空接收缓冲区
输入参数 : 无
返回值  	 : 无
备注		 : 无
**************************************************************/
void m5311_clear_recv(void)
{
	u16 i = 0;
	
	for(i = 0; i < USART2_MAX_RECV_LEN; i++)
	{	
		USART2_RX_BUF[i] = 0;	
	}
	USART2_RX_STA = 0;
}

/**************************************************************
函数名称 : m5311_check_cmd
函数功能 : m5311 发送命令后,检测接收到的应答
输入参数 : str:期待的应答结果
返回值  	 : NULL:没有得到期待的应答结果
		   其他,期待应答结果的位置(str的位置)
备注		 : 无
**************************************************************/
char* m5311_check_cmd(char *str)
{
	char *strx = 0;
	if(USART2_RX_STA & 0X8000)					/* 接收到一次数据了 */
	{ 
		USART2_RX_BUF[USART2_RX_STA&0X7FFF] = 0;/* 添加结束符 */
		strx = strstr((const char*)USART2_RX_BUF, (const char*)str);
	} 
	return strx;
}

/**************************************************************
函数名称 : m5311_send_cmd
函数功能 : m5311 发送命令
输入参数 : cmd:发送的命令字符串
		   当cmd<0XFF的时候,发送数字(比如发送0X1A),
		   大于的时候发送字符串.
		   ack:期待的应答结果,如果为空,则表示不需要等待应答
		   waittime:等待时间(单位:10ms)
返回值  	 : 0:发送成功(得到了期待的应答结果)
		   1:发送失败
备注		 : 用此函数发送命令时，命令不需加\r\n
**************************************************************/
u8 m5311_send_cmd(char *cmd, char *ack, u16 waittime)
{	
	USART2_RX_STA = 0;
	if((u32)cmd <= 0XFF)
	{
		while(0 == (USART2->SR & 0X40));/* 等待上一次数据发送完成 */
		USART3->DR = (u32)cmd;
	}
	else
	{	
		usart2_printf("%s\r\n", cmd);//发送命令
	}
	if(ack && waittime)		/* 需要等待应答 */
	{
		while(--waittime)	/* 等待倒计时 */
		{
			if(USART2_RX_STA & 0X8000)/* 接收到期待的应答结果 */
			{
				if(m5311_check_cmd(ack))/* 得到有效数据 */
				{
					break;
				}
                USART2_RX_STA = 0;
			} 
			delay_ms(10);
		}
		if(0 == waittime)
		{
			return 1;
		}
	}
	return 0;
} 

/**************************************************************
函数名称 : m5311_sleep_config
函数功能 : 模组睡眠开关
输入参数 : mode：0，关闭睡眠模式；1：开启睡眠模式
返回值  	 : 0：成功
		   1：失败
备注		 : 配置完之后，需要重启模组才能生效
**************************************************************/
u8 m5311_sleep_config(u8 mode)
{
	u8 res;

	if (mode)
	{
		res = m5311_send_cmd("AT+SM=LOCK", "OK", 300);
        m5311_send_cmd("AT+CMSYSCTRL=0,1","OK",50);   /* 打开指示灯指示功能 */
		printf("AT+SM=LOCK\r\n");
	}
	else
	{
		res = m5311_send_cmd("AT+SM=UNLOCK", "OK", 300);
        m5311_send_cmd("AT+CMSYSCTRL=0,2","OK",50);   /* 打开指示灯指示功能 */
		printf("AT+SM=UNLOCK\r\n");
	}
	
	return res;
}

/**************************************************************
函数名称 : m5311_onenet_miplcreate
函数功能 : m5311 创建 OneNET instance
输入参数 : 无
返回值  	 : 0：成功
		   1：失败
备注		 : 
**************************************************************/
u8 m5311_onenet_miplcreate(void)
{
	u8 res;
	
	res = m5311_send_cmd("AT+MIPLCREATE", "OK", 300);	
	printf("%s\r\n", "AT+MIPLCREATE");

	return res;
}

/**************************************************************
函数名称 : m5311_onenet_mipladdobj
函数功能 : 创建一个 object（对象）
输入参数 : objectid：整型，object id
		   instancecount：整型，instance数量
		   instancebitmap：二进制字符串，instance bitmap
		   例: “00101” 
		   (5 instances, only instance 1 & 3 are available)
		   attributecount：整型，attribute count
		   (具有 Read/Write 操作的 object 有 attribute)
		   actioncount：整型，action count 
		   (具有 Execute 操作的 object 有 action)
返回值  	 : 0：成功
		   1：失败
备注		 : 无
**************************************************************/
u8 m5311_onenet_mipladdobj(int objectid, int instancecount, const char *instancebitmap,
										int attributecount, int actioncount)
{
	u8 res;
	char cmd_string[64];

	memset(cmd_string, 0, sizeof(cmd_string));

	sprintf(cmd_string, "AT+MIPLADDOBJ=0,%d,%d,%s,%d,%d", objectid, instancecount, instancebitmap, attributecount, actioncount);
	
	printf("%s\r\n", cmd_string);
	
	res = m5311_send_cmd(cmd_string, "OK", 300);

	return res;
}

/**************************************************************
函数名称 : m5311_onenet_miplopen
函数功能 : 设备注册到 OneNET 平台
输入参数 : lifetime：整型，注册到OneNET平台的生存时间，单位：S
返回值  	 : 0：成功
		   1：失败
备注		 : 无
**************************************************************/
u8 m5311_onenet_miplopen(int lifetime)
{
	u8 res;
	char cmd_string[64];

	memset(cmd_string, 0, sizeof(cmd_string));
	sprintf(cmd_string, "AT+MIPLOPEN=0,%d", lifetime);
	
	printf("%s\r\n", cmd_string);
	
	res = m5311_send_cmd(cmd_string, "OK", 300);

	return res;
}

/**************************************************************
函数名称 : m5311_onenet_miplobserve_rsp
函数功能 : 模组响应平台的 observe 请求
输入参数 : msgid：整型，消息id，+MIPLOBSERVE上报的消息id
		   result：整型, observe请求的结果((取消)观察结果，
		   1表示(取消)观察成功
返回值  	 : 0：成功
		   1：失败
备注		 : 无
**************************************************************/
u8 m5311_onenet_miplobserve_rsp(int msgid, int result)
{
	u8 res;
	char cmd_string[64];

	memset(cmd_string, 0, sizeof(cmd_string));

	sprintf(cmd_string, "AT+MIPLOBSERVERSP=0,%d,%d", msgid, result);
	
	printf("%s\r\n", cmd_string);
	
	res = m5311_send_cmd(cmd_string, "OK", 300);

	return res;
}

/**************************************************************
函数名称 : m5311_onenet_mipldiscover_rsp
函数功能 : 模组响应平台的 observe 请求
输入参数 : msgid：整型，消息id，+ MIPLDISCOVER上报的消息id
		   result：整型，DISCOVER请求的结果，
		   1表示read成功，应同时提供read内容
		   length: 整型，响应DISCOVER 请求的valuestring长度
		   valuestring：字符串，响应DISCOVER请求的object对应的属性
返回值  	 : 0：成功
		   1：失败
备注		 : 多个对象属性用“;”来分开，如5900;5750
**************************************************************/
u8 m5311_onenet_mipldiscover_rsp(int msgid, int result, int length,
												const char *valuestring)
{
	u8 res;
	char cmd_string[64];

	memset(cmd_string, 0, sizeof(cmd_string));
	
	sprintf(cmd_string, "AT+MIPLDISCOVERRSP=0,%d,%d,%d,%s", msgid, result, length, valuestring);
	
	printf("%s\r\n", cmd_string);
	
	res = m5311_send_cmd(cmd_string, "OK", 300);

	return res;
}

/**************************************************************
函数名称 : m5311_onenet_miplnotify
函数功能 : 模组向平台请求同步数据
输入参数 : msgid：:整型，消息id
		   objectid :整型, 发送notify请求的object id
		   instanceid: 整型, 发送notify请求的instance id
		   resourceid:整型, 发送 notify请求的resource id
		   valuetype: 整型, 发送notify请求的上报数据类型
		   （1 string; 2 opaque; 3 integer; 4 float; 5 bool ）
		   len: 整型, 发送notify请求的上报数据长度，
		   只有 opaque 和 string 类型数据时需要配置<len>参数信息，
		   对其他类型数据（如浮点类型）则无需配置<len>参数信息。
		   value: 发送notify请求的上报数据值
		   index：整型，配置文件表示，范围从 N-1 到 0
		   flag：消息标志，1 first message; 2 middle message; 0 last message 
		   (请填 0, 用 index 来区分, 后续所有 AT 命令里的 flag 都填 0)
返回值  	 : 0：成功
		   1：失败
备注		 : value在这里无字符型，在填这个参数时请将对应的类型转换为字符型
**************************************************************/
u8 m5311_onenet_miplnotify(int msgid, int objectid, int instanceid, 
										int resourceid, int valuetype, int len,
										char *value, int index, int flag)
{
	u8 res;
	char cmd_string[256];
    
	memset(cmd_string, 0, sizeof(cmd_string));
    
	sprintf(cmd_string, "AT+MIPLNOTIFY=0,%d,%d,%d,%d,%d,%d,%s,%d,%d", msgid, objectid, instanceid, resourceid, valuetype, len, value, index, flag);
    
	printf("%s\r\n", cmd_string);
	
	res = m5311_send_cmd(cmd_string, "OK", 300);

	return res;
}

/**************************************************************
函数名称 : m5311_onenet_miplupdate
函数功能 : 注册更新命令
输入参数 : lifetime：注册到 OneNET 平台的生存时间
		   mode：1,更新objects 0，不更新objects
返回值  	 : 0：成功
		   1：失败
备注		 : 无
**************************************************************/
u8 m5311_onenet_miplupdate(int lifetime, u8 mode)
{
	u8 res;
	char cmd_string[64];

	memset(cmd_string, 0, sizeof(cmd_string));

	if(mode)
	{
		sprintf(cmd_string, "AT+MIPLUPDATE=0,%d,1", lifetime);
	}
	else
	{
		sprintf(cmd_string, "AT+MIPLUPDATE=0,%d,0", lifetime);
	}
	printf("%s\r\n", cmd_string);
	
	res = m5311_send_cmd(cmd_string, "OK", 300);

	return res;
}

/**************************************************************
函数名称 : m5311_onenet_miplwrite_rsp
函数功能 : 模组响应平台的 WRITE 请求
输入参数 : msgid：:整型，消息id，+MIPLWRITE上报的消息id
		   result：整型，write 请求的结果，2表示写入成功
返回值  	 : 0：成功
		   1：失败
备注		 : 无
**************************************************************/
u8 m5311_onenet_miplwrite_rsp(int msgid, int result)
{
	u8 res;
	char cmd_string[64];

	memset(cmd_string, 0, sizeof(cmd_string));

	sprintf(cmd_string, "AT+MIPLWRITERSP=0,%d,%d", msgid, result);
	
	printf("%s\r\n", cmd_string);
	
	res = m5311_send_cmd(cmd_string, "OK", 300);

	return res;
}

/**************************************************************
函数名称 : m5311_onenet_miplread_rsp
函数功能 : 模组响应平台的 READ 请求
输入参数 : msgid：: 整型，消息id ，+MIPLREAD 上报的消息id
		   result：整型, read 请求的结果，
		   1表示成功，应同时提供read内容
		   objectid: 整型, 响应 read 请求的 object id
		   instanceid: 整型, 响应 read 请求的 in stance id
		   resourceid: 整型, 响应 read 请求的 resource id
		   valuetype:  整型, 响应 read 请求的上报数据类型 
		   （1 string; 2 opaque; 3 integer; 4 float; 5 bool ）
		   len：整型, 响应 read 请求的上报数据长度，
		   只有 opaque 和 string 类型数据时需要配置<len>参数信息，
		   对其他类型数据（如浮点类型）则无需配置<len>参数信息。
		   value:  整型, 响应 read 请求的上报数据值
		   index：整型，配置文件表示，范围从 N-1 到 0
		   flag：整型，消息标志 ，1 first message; 2 middle message; 0 last message
		   (请填 0, 用 index 来区分, 后续所有 AT 命令里的 flag 都填 0)
返回值  	 : 0：成功
		   1：失败
备注		 : value在这里无字符型，在填这个参数时请将对应的类型转换为字符型
**************************************************************/
u8 m5311_onenet_miplread_rsp(int msgid, int result, int objectid, 
											int instanceid, int resourceid, int valuetype,
											int len, const char *value, int index, int flag)
{
	u8 res;
	char cmd_string[256];

	memset(cmd_string, 0, sizeof(cmd_string));

	sprintf(cmd_string, "AT+MIPLREADRSP=0,%d,%d,%d,%d,%d,%d,%d,%s,%d,%d", msgid, result, objectid, instanceid, resourceid, valuetype, len, value, index, flag);
	
	printf("%s\r\n", cmd_string);
	
	res = m5311_send_cmd(cmd_string, "OK", 300);

	return res;
}

/**************************************************************
函数名称 : m5311_onenet_miplexecute_rsp
函数功能 : 模组响应平台的 execute 请求
输入参数 : msgid：整型，消息id，+MIPLEXEUTERSP上报的消息id
		   result：整型，execute请求的结果，2表示execute成功
返回值  	 : 0：成功
		   1：失败
备注		 : 无
**************************************************************/
u8 m5311_onenet_miplexecute_rsp(int msgid, int result)
{
	u8 res;
	char cmd_string[64];

	memset(cmd_string, 0, sizeof(cmd_string));

	sprintf(cmd_string, "AT+MIPLEXEUTERSP=0,%d,%d", msgid, result);

	printf("%s\r\n", cmd_string);
	
	res = m5311_send_cmd(cmd_string, "OK", 300);

	return res;
}

/**************************************************************
函数名称 : m5311_onenet_miplparameter_rsp
函数功能 : 模组响应平台的设置 paramete 请求
输入参数 : msgid：整型，消息id，+MIPLPARAMETER上报的消息id
		   result：整型, 设置parameter请求的结果，1表示设置参数成功
返回值  	 : 0：成功
		   1：失败
备注		 : 无
**************************************************************/
u8 m5311_onenet_miplparameter_rsp(int msgid, int result)
{
	u8 res;
	char cmd_string[64];

	memset(cmd_string, 0, sizeof(cmd_string));

	sprintf(cmd_string, "AT+MIPLPARAMETERRSP=0,%d,%d", msgid, result);
	
	printf("%s\r\n", cmd_string);
	
	res = m5311_send_cmd(cmd_string, "OK", 300);

	return res;
}

/**************************************************************
函数名称 : m5311_onenet_miplclose
函数功能 : 模组向平台发起注销请求
输入参数 : 无
返回值  	 : 0：成功
		   1：失败
备注		 : 无
**************************************************************/
u8 m5311_onenet_miplclose(void)
{
	u8 res;
	
	res = m5311_send_cmd("AT+MIPLCLOSE=0", "OK", 300);
	printf("AT+MIPLCLOSE=0\r\n");

	return res;
}

/**************************************************************
函数名称 : m5311_onenet_mipldelobj
函数功能 : 删除一个 object（对象）
输入参数 : objectid：object id
返回值  	 : 0：成功
		   1：失败
备注		 : 无
**************************************************************/
u8 m5311_onenet_mipldelobj(int objectid)
{
	u8 res;
	char cmd_string[64];

	memset(cmd_string, 0, sizeof(cmd_string));

	sprintf(cmd_string, "AT+MIPLDELOBJ=0,%d", objectid);
	
	printf("%s\r\n", cmd_string);
	
	res = m5311_send_cmd(cmd_string, "OK", 300);
	
	return res;
}

/**************************************************************
函数名称 : m5311_onenet_mipldelete
函数功能 : 删除 OneNET instance
输入参数 : 无
返回值  	 : 0：成功
		   1：失败
备注		 : 无
**************************************************************/
u8 m5311_onenet_mipldelete(void)
{
	u8 res;
	
	res = m5311_send_cmd("AT+MIPLDELETE=0", "OK", 300);
	printf("AT+MIPLDELETE=0\r\n");

	return res;
}

/**************************************************************
函数名称 : m5311_parse_onenet_miplobserve
函数功能 : 解析平台向模组发起 observe 请求参数
输入参数 : 要解析的参数
返回值  	 : 无
备注		 : 无
**************************************************************/
void m5311_parse_onenet_miplobserve(int *msgid, int *flag, int *objectid, int *instanceid, int *resourceid)
{
	char *token = NULL;

   	/* 用strtok函数解析 */
   	token = strtok(strstr((const char*)USART2_RX_BUF, "+MIPLOBSERVE"), ", ");
   	token = strtok(NULL, ", ");
   	token = strtok(NULL, ", ");
   	*msgid = myatoi(token);
   	token = strtok(NULL, ", ");
   	*flag = myatoi(token);
   	token = strtok(NULL, ", ");
   	*objectid = myatoi(token);
   	token = strtok(NULL, ", ");
   	*instanceid = myatoi(token);
   	token = strtok(NULL, ", ");
   	*resourceid = myatoi(token);
}

/**************************************************************
函数名称 : m5311_parse_onenet_mipldiscover
函数功能 : 解析平台向模组发起 discover 请求参数
输入参数 : 要解析的参数
返回值  	 : 无
备注		 : 无
**************************************************************/
void m5311_parse_onenet_mipldiscover(int *msgid, int *objectid)
{
   char *token = NULL;
 
   /* 用strtok函数解析 */
   token = strtok(strstr((const char*)USART2_RX_BUF, "+MIPLDISCOVER"), ", ");
   token = strtok(NULL, ", ");
   token = strtok(NULL, ", ");
   *msgid = myatoi(token);
   token = strtok(NULL, ", ");
   *objectid = myatoi(token);
}

/**************************************************************
函数名称 : m5311_parse_onenet_mipldwrite
函数功能 : 解析平台向模组发起 write 请求参数
输入参数 : 要解析的参数
返回值  	 : 无
备注		 : 无
**************************************************************/
void m5311_parse_onenet_mipldwrite(int *msgid, int *objectid, int *instanceid, 
											int *resourceid, int *valuetype, int *len, 
											char *value, int *flag, int *index)
{
   char *token = NULL;
   
   /* 用strtok函数解析 */
   token = strtok(strstr((const char*)USART2_RX_BUF, "+MIPLWRITE"), ", ");
   token = strtok(NULL, ", ");
   token = strtok(NULL, ", ");
   *msgid = myatoi(token);
   token = strtok(NULL, ", ");
   *objectid = myatoi(token);
   token = strtok(NULL, ", ");
   *instanceid = myatoi(token);
   token = strtok(NULL, ", ");
   *resourceid = myatoi(token);
   token = strtok(NULL, ", ");
   *valuetype = myatoi(token);
   token = strtok(NULL, ", ");
   *len = myatoi(token);
   token = strtok(NULL, ", ");
   sprintf((char*)value, "%s", token);
   token = strtok(NULL, ", ");
   *flag = myatoi(token);
   token = strtok(NULL, ", ");
   *index = myatoi(token);
}

/**************************************************************
函数名称 : m5311_parse_onenet_miplread
函数功能 : 解析OneNET 平台向模组发起 read 请求参数
输入参数 : 要解析的参数
返回值  	 : 无
备注		 : 无
**************************************************************/
void m5311_parse_onenet_miplread(int *msgid, int *objectid, int *instanceid, int *resourceid)
{
   char *token = NULL;
   
   /* 用strtok函数解析 */
   token = strtok(strstr((const char*)USART2_RX_BUF, "+MIPLREAD"), ", ");
   token = strtok(NULL, ", ");
   token = strtok(NULL, ", ");
   *msgid = myatoi(token);
   token = strtok(NULL, ", ");
   *objectid = myatoi(token);
   token = strtok(NULL, ", ");
   *instanceid = myatoi(token);
   token = strtok(NULL, ", ");
   *resourceid = myatoi(token);
}

/**************************************************************
函数名称 : m5311_registered_to_onenet
函数功能 : 设备注册到OneNET平台
输入参数 : 无
返回值  	 : 无
备注		 : 无
**************************************************************/
void m5311_registered_to_onenet(void)
{	
	if(0 == m5311_onenet_miplclose())
	{
		printf("AT+MIPLCLOSE OK\r\n");
	}
	delay_ms(300);
	if(0 == m5311_onenet_mipldelobj(g_addobj_objectid_smokesensor))
	{
		printf("AT+MIPLDELOBJ OK\r\n");
	}
	delay_ms(300);
	if(0 == m5311_onenet_mipldelete())
	{
		printf("AT+MIPLDELETE OK\r\n");
	}
	delay_ms(300);
	if(0 == m5311_onenet_miplcreate())
	{
		printf("AT+MIPLCREATE OK\r\n");
	}
	delay_ms(300);
	if(0 == m5311_onenet_mipladdobj(g_addobj_objectid_smokesensor, 1, "\"1\"", 1, 0))
	{
		printf("AT+MIPLADDOBJ OK\r\n");
	}
	delay_ms(300);
	if(0 == m5311_onenet_miplopen(g_opend_lifetime))
	{
		printf("AT+MIPLOPEN OK\r\n");
	}
	delay_ms(300);
}

/**************************************************************
函数名称 : m5311_onenet_miplnotify_process
函数功能 : 数据上报到OneNET平台
输入参数 : 无
返回值  	 : 无
备注		 : 无
**************************************************************/
void m5311_onenet_miplnotify_process(void)
{
    /* 局部变量，用于保存转换计算后的电压值 */ 
    float ADC_ConvertedValueLocal; 
	TIM_SetCounter(TIM3, 0);	        /* 计数器清空 */
	TIM_Cmd(TIM3, DISABLE);  	        /* 关闭TIMx */
	g_hardware_times = 0;
    
	printf("notify to onenet\r\n");	
    
    ADC_ConvertedValueLocal =(float) ADC_ConvertedValue * 99 / 4096.0;      /* 读取转换的AD值 */
    printf("%.2f\r\n" ,ADC_ConvertedValueLocal);        /* 把AD值转换成百分比0~99 */
    
	sprintf(smokesensor_value ,"\"%f\"" ,ADC_ConvertedValueLocal);	
    
	m5311_onenet_miplnotify(g_observe_msgid, g_observe_objectid_smokesensor, g_observe_instanceid, g_notify_resourceid_5700_smokesensor, 4, 2, smokesensor_value, 0, 0);
	delay_ms(3000);
	
	m5311_onenet_miplupdate(g_opend_lifetime, 1);	

	g_m5311_miplnotify_flag = 0;
				
	TIM_Cmd(TIM3, ENABLE);  	/* 使能TIMx */
}

/***********************************************************************
* 函数名  : init_m5311
* 描述    : m5311模块初始化
* 输入    : void
* 输出    : void
* 入口参数: 
* 出口参数: 
* 备注    : 1.通过发送AT检测是否接入模块，若返回OK则已接入
            2.当找到M5310模块时，打开指示灯、关闭睡眠模式
            3.发送指令请求创建实例，若返回 +MIPLCREATE:0 则添加成功
              等待8s后仍未收到，则判定为创建失败，0.5秒后重新创建
            4.发送指令请求添加OBJ，若返回 OK 则添加成功
              等待8s后仍未收到，则判定为添加失败，0.5秒后重新添加
            5.指定资源列表，若等待2s内返回 OK 则指定成功
            6.向onenet平台注册或查询注册状态，若返回 +MIPLEVENT:0,6 
              则添加成功,等待8s后仍未收到，则判定为创建失败，
              等待0.5秒后重新创建
            7.初始化完成，设定设备在线时间60S
************************************************************************/
void init_m5311(void)
{
    m5311_power_on();    /* 启动M5311 */
    
    /* 检测是否接入模块 */
    while(m5311_send_cmd("AT","OK",50))
    {       
        /* 未找到模块,继续尝试启动 */
        m5311_power_on();
        delay_ms(1000);
    }
    
    /* 找到模块,启动指示灯,关闭睡眠模式 */
    m5311_sleep_config(0);        

    /* 请求创建实例 */
    while(m5311_onenet_miplcreate())
    {       
        /* 删除创建失败的实例 */
        m5311_onenet_mipldelete();
        delay_ms(500);
    }

    /**************** 请求添加OBJ1(5700:光照数据上报) *******************/
    while(m5311_onenet_mipladdobj(g_addobj_objectid_smokesensor, 1, "\"1\"", 1, 0))
    {
        /* 删除添加失败的OBJ */
        m5311_onenet_mipldelobj(g_addobj_objectid_smokesensor);
        delay_ms(500);
    }

    /* 创建资源列表 */
    m5311_onenet_mipldiscover_rsp(g_discover_msgid_smokesensor, 1, 4, g_discover_valuestring_smokesensor);
    
    /* 向onenet平台注册或查询注册状态 */
    while(m5311_onenet_miplopen(g_opend_lifetime))
    {
        /* 注册失败,重新注册 */
    }

    /* 向onenet平台注册成功，设定设备在线时间300S */
    m5311_onenet_miplupdate(300, 0);
}

/**************************************************************
函数名称 : TIM3_IRQHandler
函数功能 : 定时器3中断服务函数
输入参数 : 无
返回值  	 : 无
备注		 : 定时来notify数据
**************************************************************/
void TIM3_IRQHandler(void)
{	
	if(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)  /* 检查TIM3更新中断发生与否 */
	{
		TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  /* 清除TIMx更新中断标志 */

	//	printf("g_hardware_times=%d\r\n", g_hardware_times);
		g_hardware_times++;
		
		if(g_hardware_times > M5311_MIPLNOTIFY_TIME)
		{
			g_m5311_miplnotify_flag = 1;
			printf("enter notify, g_hardware_times=%d\r\n", g_hardware_times);
			g_hardware_times = 0;
		}
	}
}
